/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.rpc;

import cn.hutool.core.collection.ListUtil;
import com.beust.jcommander.internal.Lists;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.auth.AuthLoginManager;
import com.je.auth.AuthSessionTemplate;
import com.je.common.auth.AuthAccount;
import com.je.common.base.DynaBean;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaResourceService;
import com.je.common.base.service.MetaService;
import com.je.common.base.util.SecurityUserHolder;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.rpc.func.MetaFuncRpcService;
import com.je.rbac.cache.*;
import com.je.rbac.expcetion.RbacException;
import com.je.rbac.service.grant.develop.RbacGrantDevelopPcFuncPermmisionService;
import com.je.rbac.service.permission.*;
import com.je.rbac.service.permission.template.*;
import com.je.rbac.service.role.RbacRoleService;
import org.apache.servicecomb.provider.pojo.RpcSchema;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@RpcSchema(schemaId = "permissionRpcService")
public class PermissionRpcServiceImpl implements PermissionRpcService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private AccountRpcService accountRpcService;
    @Autowired
    private RbacPermmisionBaseService rbacPermmisionBaseService;
    @Autowired
    private AccountPermissionCache accountPermissionCache;
    @Autowired
    private FuncPermissionCache funcPermissionCache;
    @Autowired
    private PcMenuDataService pcMenuDataService;
    @Autowired
    private PcFuncBaseService pcFuncBaseService;
    @Autowired
    private PcFuncButtonService pcFuncButtonService;
    @Autowired
    private PcPluginBaseService pcPluginBaseService;
    @Autowired
    private RbacRoleService rbacRoleService;
    @Autowired
    private MetaFuncRpcService metaFuncRpcService;
    @Autowired
    private AccountProductCache accountProductCache;
    @Autowired
    private RbacGrantDevelopPcFuncPermmisionService rbacGrantDevelopPcFuncPermmisionService;
    @Autowired
    private PcSubFuncRelationService pcSubFuncRelationService;
    @Autowired
    private PermissionRpcService permissionRpcService;
    @Autowired
    private PermissionLoadService permissionLoadService;
    @Autowired
    private MetaResourceService metaResourceService;
    @Autowired
    private RolePermCache rolePermCache;
    @Autowired
    private DepartmentPermCache departmentPermCache;
    @Autowired
    private OrgPermCache orgPermCache;
    @Autowired
    private DevelopRolePermCache developRolePermCache;
    @Autowired
    private PermGroupPermCache permGroupPermCache;
    @Autowired
    private UserPermCache userPermCache;
    @Autowired
    private AuthLoginManager authLoginManager;
    @Autowired
    private AuthSessionTemplate authSessionTemplate;

    @Override
    public List<String> findAccountPermissionsWithLoginId(String loginId, String tenantId) {
        Object account = authSessionTemplate.get(authLoginManager.getSession(), "account");
        if (account == null) {
            return null;
        }
        AuthAccount authAccount = (AuthAccount) account;
        return findAccountPermissions(authAccount.getDeptId(), loginId, tenantId);
    }

    @Override
    public List<String> findAccountPermissions(String departmentId, String accountId, String tenantId) {
        List<String> accountPermissionList;
        if (Strings.isNullOrEmpty(tenantId)) {
            accountPermissionList = accountPermissionCache.getCacheValue(accountId);
        } else {
            accountPermissionList = accountPermissionCache.getCacheValue(tenantId, accountId);
        }

        if (accountPermissionList != null && !accountPermissionList.isEmpty()) {
            return accountPermissionList;
        }

        accountPermissionList = new ArrayList<>();
        DynaBean accountBean = metaService.selectOne("JE_RBAC_ACCOUNT", ConditionsWrapper.builder().eq("JE_RBAC_ACCOUNT_ID", accountId));
        if (accountBean == null) {
            return null;
        }

        //角色权限
        List<String> roleIdList = accountRpcService.findAccountRoleIds(tenantId, accountId);
        if (roleIdList != null && roleIdList.size() > 0) {
            List<List<String>> rolePermList = rolePermCache.getCacheValues(roleIdList);
            for (int i = 0; rolePermList != null && !rolePermList.isEmpty() && i < rolePermList.size(); i++) {
                if (rolePermList.get(i) != null) {
                    accountPermissionList.addAll(rolePermList.get(i));
                }
            }
            List<List<String>> developRolePermList = developRolePermCache.getCacheValues(roleIdList);
            for (int i = 0; developRolePermList != null && !developRolePermList.isEmpty() && i < developRolePermList.size(); i++) {
                if (developRolePermList.get(i) != null) {
                    accountPermissionList.addAll(developRolePermList.get(i));
                }
            }
            //权限组权限
            List<DynaBean> roleBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder().in("JE_RBAC_ROLE_ID", roleIdList));
            List<String> permGroupIdList = new ArrayList<>();
            for (DynaBean eachRoleBean : roleBeanList) {
                if (!Strings.isNullOrEmpty(eachRoleBean.getStr("ROLE_PERMGROUP_ID"))) {
                    permGroupIdList.addAll(Splitter.on(",").splitToList(eachRoleBean.getStr("ROLE_PERMGROUP_ID")));
                }
            }
            List<List<String>> permGroupPermList = permGroupPermCache.getCacheValues(permGroupIdList);
            for (int i = 0; permGroupPermList != null && !permGroupPermList.isEmpty() && i < permGroupPermList.size(); i++) {
                if (permGroupPermList.get(i) != null) {
                    accountPermissionList.addAll(permGroupPermList.get(i));
                }
            }
        }

        List<String> orgPermList = orgPermCache.getCacheValue(accountBean.getStr("SY_ORG_ID"));
        if (orgPermList != null) {
            accountPermissionList.addAll(orgPermList);
        }

        //部门权限
        List<String> deptPermList = departmentPermCache.getCacheValue(departmentId);
        if (deptPermList != null) {
            accountPermissionList.addAll(deptPermList);
        }

        List<String> userPermList = userPermCache.getCacheValue(accountBean.getStr("USER_ASSOCIATION_ID"));
        if (userPermList != null) {
            accountPermissionList.addAll(userPermList);
        }

        //去重，在前边去重业务太冗余
        accountPermissionList = accountPermissionList.stream().distinct().collect(Collectors.toList());

        if (Strings.isNullOrEmpty(tenantId)) {
            accountPermissionCache.putCache(accountId, accountPermissionList);
        } else {
            accountPermissionCache.putCache(tenantId, accountId, accountPermissionList);
        }

        return accountPermissionList;
    }

    @Override
    public List<String> findAccountPluginPermissions(String departmentId, String accountId, String tenantId, String pluginCode) {
        List<String> accountPermList = findAccountPermissions(departmentId, accountId, tenantId);
        if (accountPermList == null || accountPermList.isEmpty()) {
            return new ArrayList<>();
        }
        return accountPermList.stream().filter(each -> each.equals(pcPluginBaseService.formatPcPluginShowTemplate(pluginCode))).collect(Collectors.toList());
    }

    @Override
    public List<String> findAccountFuncPermissions(String departmentId, String accountId, String tenantId, String funcCode) {
        String subKey = String.format("%s_%s", accountId, funcCode);
        List<String> funcPermissionList;
        if (Strings.isNullOrEmpty(tenantId)) {
            funcPermissionList = funcPermissionCache.getCacheValue(subKey);
        } else {
            funcPermissionList = funcPermissionCache.getCacheValue(tenantId, subKey);
        }

        if (funcPermissionList != null && !funcPermissionList.isEmpty()) {
            return funcPermissionList;
        }

        funcPermissionList = new ArrayList<>();
        DynaBean accountBean = metaService.selectOne("JE_RBAC_ACCOUNT", ConditionsWrapper.builder().eq("JE_RBAC_ACCOUNT_ID", accountId));
        if (accountBean == null) {
            return null;
        }

        //角色权限
        List<String> roleIdList = accountRpcService.findAccountRoleIds(tenantId, accountId);
        List<Map<String, Object>> rolePermissionBeanList = rbacPermmisionBaseService.findRoleFuncPermissions(roleIdList, funcCode);
        if (rolePermissionBeanList != null && !rolePermissionBeanList.isEmpty()) {
            for (Map<String, Object> eachRolePermBean : rolePermissionBeanList) {
                if ("0".equals(eachRolePermBean.get("ROLEPERM_EXCLUDE_CODE"))) {
                    if (!funcPermissionList.contains(eachRolePermBean.get("PERM_CODE").toString())) {
                        funcPermissionList.add(eachRolePermBean.get("PERM_CODE").toString());
                    }
                } else {
                    if (!"1".equals(eachRolePermBean.get("ROLEPERM_NOT_CHECKED"))) {
                        if (!funcPermissionList.contains(eachRolePermBean.get("PERM_CODE").toString())) {
                            funcPermissionList.add(eachRolePermBean.get("PERM_CODE").toString());
                        }

                    }
                }
            }
        }

        List<String> permGroupIdList = new ArrayList<>();
        //权限组权限
        List<DynaBean> roleBeanList = metaService.select("JE_RBAC_ROLE", ConditionsWrapper.builder().in("JE_RBAC_ROLE_ID", roleIdList));
        if (roleBeanList != null && !roleBeanList.isEmpty()) {
            for (DynaBean eachRoleBean : roleBeanList) {
                if (!Strings.isNullOrEmpty(eachRoleBean.getStr("ROLE_PERMGROUP_ID"))) {
                    permGroupIdList.addAll(Splitter.on(",").splitToList(eachRoleBean.getStr("ROLE_PERMGROUP_ID")));
                }
            }
        }

        List<Map<String, Object>> permGroupPermissionBeanList = rbacPermmisionBaseService.findPermGroupFuncPermissions(permGroupIdList, funcCode);
        if (permGroupPermissionBeanList != null && !permGroupPermissionBeanList.isEmpty()) {
            for (Map<String, Object> eachBean : permGroupPermissionBeanList) {
                if (!funcPermissionList.contains(eachBean.get("PERM_CODE"))) {
                    funcPermissionList.add(eachBean.get("PERM_CODE").toString());
                }
            }
        }


        //机构权限
        List<Map<String, Object>> orgPermissionBeanList = rbacPermmisionBaseService.findOrgFuncPermissions(accountBean.getStr("SY_ORG_ID"), funcCode);
        if (orgPermissionBeanList != null && !orgPermissionBeanList.isEmpty()) {
            for (Map<String, Object> eachBean : orgPermissionBeanList) {
                if (!funcPermissionList.contains(eachBean.get("PERM_CODE"))) {
                    funcPermissionList.add(eachBean.get("PERM_CODE").toString());
                }
            }
        }

        //部门权限
        List<String> deptIdList = accountRpcService.findAccountDeptIds(tenantId, accountId);
        List<Map<String, Object>> deptPermissionBeanList = rbacPermmisionBaseService.findDepartmentFuncPermissions(deptIdList, funcCode);
        if (deptPermissionBeanList != null && !deptPermissionBeanList.isEmpty()) {
            for (Map<String, Object> eachBean : deptPermissionBeanList) {
                if (!funcPermissionList.contains(eachBean.get("PERM_CODE"))) {
                    funcPermissionList.add(eachBean.get("PERM_CODE").toString());
                }
            }
        }

        //人员权限
        String userId = accountBean.getStr("USER_ASSOCIATION_ID");
        List<Map<String, Object>> topMenuList = rbacPermmisionBaseService.findUserFuncPermissions(userId, funcCode);
        if (topMenuList != null && !topMenuList.isEmpty()) {
            for (Map<String, Object> eachBean : topMenuList) {
                if (!funcPermissionList.contains(eachBean.get("PERM_CODE"))) {
                    funcPermissionList.add(eachBean.get("PERM_CODE").toString());
                }
            }
        }

        if (Strings.isNullOrEmpty(tenantId)) {
            funcPermissionCache.putCache(subKey, funcPermissionList);
        } else {
            funcPermissionCache.putCache(tenantId, subKey, funcPermissionList);
        }

        return funcPermissionList;
    }

    @Override
    public List<String> findAccountMenuPermissions(String departmentId, String accountId, String tenantId) {
        List<String> accountPermList = findAccountPermissions(departmentId, accountId, tenantId);
        if (accountPermList == null || accountPermList.isEmpty()) {
            return new ArrayList<>();
        }
        return accountPermList.stream().filter(each -> each.startsWith("menu-")).collect(Collectors.toList());
    }

    @Override
    public List<String> findAccountTopMenuPermissions(String departmentId, String accountId, String tenantId) {
        List<String> accountPermList = findAccountPermissions(departmentId, accountId, tenantId);
        if (accountPermList == null || accountPermList.isEmpty()) {
            return new ArrayList<>();
        }
        return accountPermList.stream().filter(each -> each.startsWith("topmenu-")).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void quickGrantMenu(String productId, String menuId) {
        DynaBean menuBean = metaService.selectOneByPk("JE_CORE_MENU", menuId);
        if (menuBean == null) {
            throw new RbacException("不存在此菜单！");
        }
        DynaBean productRole = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("SY_PRODUCT_ID", productId).eq("ROLE_DEVELOP", "1"));
        if (productRole == null) {
            throw new RbacException("不存此产品角色！");
        }

        DynaBean menuShowPermBean = pcMenuDataService.writeMenuDataShowTemplate(menuId, true);
        saveRolePermAssocaition(productRole.getStr("JE_RBAC_ROLE_ID"), Lists.newArrayList(menuShowPermBean));

        if ("MT".equals(menuBean.getStr("MENU_NODEINFOTYPE"))) {
            quickGranFunc(productId, menuBean.getStr("MENU_NODEINFO"));
        } else if ("IDDT".equals(menuBean.getStr("MENU_NODEINFOTYPE"))) {
            quickGranPlugin(productId, menuBean.getStr("MENU_NODEINFO"));
        } else {
            quickGranPlugin(productId, menuBean.getStr("MENU_NODEINFO"));
        }

        permissionLoadService.reloadDevelopRolePermCache(Lists.newArrayList(productRole.getStr("JE_RBAC_ROLE_ID")));
    }

    private String getFuncCode(DynaBean funcBean) {
        if (funcBean == null) {
            return null;
        }
        return funcBean.getStr("FUNCINFO_FUNCCODE");
    }

    @Override
    @Transactional
    public void quickGranFunc(String productId, String funcCode) {
        DynaBean productRole = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("SY_PRODUCT_ID", productId).eq("ROLE_DEVELOP", "1"));
        if (productRole == null) {
            throw new RbacException("不存此产品角色！");
        }

        //查找需要授权的功能及功能
        Map<String, List<DynaBean>> funcResult = metaFuncRpcService.findPermedFuncsAndChildFuncsWithButtonsByFuncCodes(Lists.newArrayList(funcCode));
        //主功能
        List<DynaBean> mainFuncList = funcResult.get("main");
        //子功能关系
        List<DynaBean> subFuncRelationList = funcResult.get("child");
        //主子功能涉及到的按钮
        List<DynaBean> funcButtonList = funcResult.get("button") == null ? new ArrayList<>() : funcResult.get("button");

        Map<String, List<String>> aggregateFuncButtonMap = new HashMap<>();
        List<DynaBean> funcPermBeanList = new ArrayList<>();
        DynaBean eachFuncPermBean;
        List<String> eachFuncButtonList;

        //写入子功能关系权限
        if (subFuncRelationList != null && !subFuncRelationList.isEmpty()) {
            Map<String, DynaBean> subFuncParentFuncMap = metaFuncRpcService.findSubFuncParentFuncInfos(subFuncRelationList.stream().map(each -> each.getStr("JE_CORE_FUNCRELATION_ID")).collect(Collectors.toList()));
            if (subFuncParentFuncMap != null && !subFuncParentFuncMap.isEmpty()) {
                for (DynaBean eachSubFuncRelationBean : subFuncRelationList) {
                    funcPermBeanList.addAll(pcSubFuncRelationService.writePcSubFuncRelationPermission(getFuncCode(subFuncParentFuncMap.get(eachSubFuncRelationBean.getStr("JE_CORE_FUNCRELATION_ID"))), eachSubFuncRelationBean.getStr("FUNCRELATION_CODE"), true, true));
                }
            }
        }

        //主功能
        for (DynaBean eachFuncBean : mainFuncList) {
            eachFuncPermBean = pcFuncBaseService.writePcFuncShowPermission(eachFuncBean.getStr("FUNCINFO_FUNCCODE"), true);
            funcPermBeanList.add(eachFuncPermBean);
            //给功能增加配置
            rbacGrantDevelopPcFuncPermmisionService.saveDevelopFuncConfigPermission(productRole.getStr("JE_RBAC_ROLE_ID"), eachFuncBean.getStr("FUNCINFO_FUNCCODE"), GrantTypeEnum.MENU);
            if (!aggregateFuncButtonMap.containsKey(eachFuncBean.getStr("FUNCINFO_FUNCCODE"))) {
                eachFuncButtonList = new ArrayList<>();
                aggregateFuncButtonMap.put(eachFuncBean.getStr("FUNCINFO_FUNCCODE"), eachFuncButtonList);
            } else {
                eachFuncButtonList = aggregateFuncButtonMap.get(eachFuncBean.getStr("FUNCINFO_FUNCCODE"));
            }

            for (DynaBean eachButtonBean : funcButtonList) {
                if (eachFuncBean.getStr("JE_CORE_FUNCINFO_ID").equals(eachButtonBean.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                    eachFuncButtonList.add(eachButtonBean.getStr("RESOURCEBUTTON_CODE"));
                }
            }
        }

        //子功能-对应的功能授权
        for (int i = 0; subFuncRelationList != null && !subFuncRelationList.isEmpty() && i < subFuncRelationList.size(); i++) {
            if (!"func".equals(subFuncRelationList.get(i).getStr("FUNCRELATION_RELYONTYPE"))) {
                continue;
            }
            eachFuncPermBean = pcFuncBaseService.writePcFuncShowPermission(subFuncRelationList.get(i).getStr("FUNCRELATION_CODE"), true);
            funcPermBeanList.add(eachFuncPermBean);
            //给功能增加配置权限
            rbacGrantDevelopPcFuncPermmisionService.saveDevelopFuncConfigPermission(productRole.getStr("JE_RBAC_ROLE_ID"), subFuncRelationList.get(i).getStr("FUNCRELATION_CODE"), GrantTypeEnum.MENU);
            if (!aggregateFuncButtonMap.containsKey(subFuncRelationList.get(i).getStr("FUNCRELATION_CODE"))) {
                eachFuncButtonList = new ArrayList<>();
                aggregateFuncButtonMap.put(subFuncRelationList.get(i).getStr("FUNCRELATION_CODE"), eachFuncButtonList);
            } else {
                eachFuncButtonList = aggregateFuncButtonMap.get(subFuncRelationList.get(i).getStr("FUNCRELATION_CODE"));
            }

            for (DynaBean eachButtonBean : funcButtonList) {
                if (subFuncRelationList.get(i).getStr("FUNCRELATION_FUNCID").equals(eachButtonBean.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                    eachFuncButtonList.add(eachButtonBean.getStr("RESOURCEBUTTON_CODE"));
                }
            }
        }

        saveRolePermAssocaition(productRole.getStr("JE_RBAC_ROLE_ID"), funcPermBeanList);
        quickGrantFuncButton(productId, aggregateFuncButtonMap);

        permissionLoadService.reloadDevelopRolePermCache(Lists.newArrayList(productRole.getStr("JE_RBAC_ROLE_ID")));
    }

    @Override
    @Transactional
    public void quickGranSubFunc(String productId, String subFuncRelationId) {
        DynaBean productRole = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("SY_PRODUCT_ID", productId).eq("ROLE_DEVELOP", "1"));
        if (productRole == null) {
            throw new RbacException("不存此产品角色！");
        }

        DynaBean subFuncRelationBean = metaResourceService.selectOneByNativeQuery("JE_CORE_FUNCRELATION",
                NativeQuery.build().eq("JE_CORE_FUNCRELATION_ID", subFuncRelationId));
        if (subFuncRelationBean == null) {
            throw new RbacException("不存在此子功能！");
        }

        List<DynaBean> funcPermBeanList = new ArrayList<>();
        Map<String, DynaBean> subFuncParentFuncMap = metaFuncRpcService.findSubFuncParentFuncInfos(Lists.newArrayList(subFuncRelationId));
        funcPermBeanList.addAll(pcSubFuncRelationService.writePcSubFuncRelationPermission(getFuncCode(subFuncParentFuncMap.get(subFuncRelationBean.getStr("JE_CORE_FUNCRELATION_ID"))), subFuncRelationBean.getStr("FUNCRELATION_CODE"), true, true));
        saveRolePermAssocaition(productRole.getStr("JE_RBAC_ROLE_ID"), funcPermBeanList);
        if ("func".equals(subFuncRelationBean.getStr("FUNCRELATION_RELYONTYPE"))) {
            DynaBean funcInfo = metaResourceService.selectOneByPk("JE_CORE_FUNCINFO", subFuncRelationBean.getStr("FUNCRELATION_FUNCID"));
            quickGranFunc(productId, funcInfo.getStr("FUNCINFO_FUNCCODE"));
        }

        permissionLoadService.reloadDevelopRolePermCache(Lists.newArrayList(productRole.getStr("JE_RBAC_ROLE_ID")));
    }

    @Override
    @Transactional
    public void quickGranPlugin(String productId, String pluginCode) {
        DynaBean productRole = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("SY_PRODUCT_ID", productId).eq("ROLE_DEVELOP", "1"));
        if (productRole == null) {
            throw new RbacException("不存此产品角色！");
        }
        List<DynaBean> pluginBasePermissionList = new ArrayList<>();
        pluginBasePermissionList.add(pcPluginBaseService.writePcPluginShowPermission(pluginCode, true));

        saveRolePermAssocaition(productRole.getStr("JE_RBAC_ROLE_ID"), pluginBasePermissionList);

        permissionLoadService.reloadDevelopRolePermCache(Lists.newArrayList(productRole.getStr("JE_RBAC_ROLE_ID")));
    }

    @Override
    @Transactional
    public void quickGrantFuncButton(String productId, Map<String, List<String>> funcButtonMap) {
        List<DynaBean> funcButtonPermBeanList = new ArrayList<>();
        String accountId = SecurityUserHolder.getCurrentAccountId();
        for (String eachFuncCode : funcButtonMap.keySet()) {
            String subKey = String.format("%s_%s", accountId, eachFuncCode);
            funcPermissionCache.removeCache(subKey);
            for (String eachButtonCode : funcButtonMap.get(eachFuncCode)) {
                funcButtonPermBeanList.add(pcFuncButtonService.writePcFuncButtonShowPermission(eachFuncCode, eachButtonCode, true));
            }
        }

        DynaBean productRole = metaService.selectOne("JE_RBAC_ROLE", ConditionsWrapper.builder()
                .eq("SY_PRODUCT_ID", productId).eq("ROLE_DEVELOP", "1"));
        if (productRole == null) {
            throw new RbacException("不存此产品角色！");
        }

        saveRolePermAssocaition(productRole.getStr("JE_RBAC_ROLE_ID"), funcButtonPermBeanList);

        permissionLoadService.reloadAllDevelopRolePermCache();
    }

    /**
     * 保存关系
     *
     * @param roleId
     * @param permissionList
     */
    private void saveRolePermAssocaition(String roleId, List<DynaBean> permissionList) {
        //查询已存在的关联关系
        List<String> permissionIdList = new ArrayList<>();
        for (DynaBean eachPermissionBean : permissionList) {
            permissionIdList.add(eachPermissionBean.getStr("JE_RBAC_PERM_ID"));
        }
        Set<String> extendRoleIdList = rbacRoleService.findExtendRoleIds(Lists.newArrayList(roleId));
        extendRoleIdList.add(roleId);

        List<DynaBean> associationList = metaService.select("JE_RBAC_ROLEPERM", ConditionsWrapper.builder()
                .eq("ROLEPERM_GRANTTYPE_CODE", GrantTypeEnum.MENU.name())
                .in("JE_RBAC_ROLE_ID", extendRoleIdList)
                .in("JE_RBAC_PERM_ID", permissionIdList));
        List<String> havedRolePermissionList = new ArrayList<>();
        for (DynaBean eachAssociationBean : associationList) {
            havedRolePermissionList.add(eachAssociationBean.getStr("JE_RBAC_PERM_ID"));
        }
        //写入关联关系
        DynaBean rolePermBean;
        for (DynaBean eachPermissionBean : permissionList) {
            //如果是正常权限，不是排他权限，则不做任何处理，如果是排他权限，则需要设置ROLEPERM_NOT_CHECKED
            if (havedRolePermissionList.contains(eachPermissionBean.getStr("JE_RBAC_PERM_ID"))) {
                continue;
            }

            rolePermBean = new DynaBean("JE_RBAC_ROLEPERM", false);
            rolePermBean.set("JE_RBAC_ROLE_ID", roleId);
            rolePermBean.set("JE_RBAC_PERM_ID", eachPermissionBean.getStr("JE_RBAC_PERM_ID"));
            rolePermBean.set("ROLEPERM_EXCLUDE_CODE", "0");
            rolePermBean.set("ROLEPERM_EXCLUDE_NAME", "否");
            //授权方式
            rolePermBean.set("ROLEPERM_TYPE_CODE", GrantMethodEnum.ROLE.name());
            rolePermBean.set("ROLEPERM_TYPE_NAME", GrantMethodEnum.ROLE.getDesc());
            //授权类型
            rolePermBean.set("ROLEPERM_GRANTTYPE_CODE", GrantTypeEnum.MENU.name());
            rolePermBean.set("ROLEPERM_GRANTTYPE_NAME", GrantTypeEnum.MENU.getDesc());
            //todo 设置租户信息
            commonService.buildModelCreateInfo(eachPermissionBean);
            metaService.insert(rolePermBean);
        }
    }

    @Override
    public void clearRoleAccountPermissions(String tenantId, List<String> roleIdList) {
        permissionLoadService.reloadDevelopRolePermCache(roleIdList);
        permissionLoadService.reloadRolePermCache(roleIdList, true);
    }

    @Override
    public void clearDeptAccountPermissions(String tenantId, List<String> deptIdList) {
        permissionLoadService.reloadDepartmentPermCache(deptIdList);
    }

    @Override
    public void clearOrgAccountPermissions(String tenantId, List<String> orgIdList) {
        permissionLoadService.reloadOrgPermCache(orgIdList);
    }

    @Override
    public void clearAccountPermissions(String tenantId, List<String> acountIdList) {
        accountPermissionCache.removeCache(acountIdList);
    }

    @Override
    public void clearPermGroupAccountPermissions(String tenantId, List<String> permGroupIdList) {
        permissionLoadService.reloadPermGroupPermCache(permGroupIdList, true);
    }

    @Override
    public void transferFuncPermission(String originalFuncCode, String targetFuncCode) {
        //查找需要授权的功能及功能
        Map<String, List<DynaBean>> funcResult = metaFuncRpcService.findPermedFuncsAndChildFuncsWithButtonsByFuncCodes(Lists.newArrayList(originalFuncCode));
        List<DynaBean> funcList = new ArrayList<>();
        funcList.addAll(funcResult.get("main"));
        funcList.addAll(funcResult.get("child"));
        List<DynaBean> funcButtonList = funcResult.get("button") == null ? new ArrayList<>() : funcResult.get("button");

        List<String> permCodeList = new ArrayList<>();
        //用于根据权限找到按钮编码
        Map<String, String> buttonPermMap = new HashMap<>();
        for (DynaBean eachFuncBean : funcList) {
            //功能权限
            permCodeList.add(pcFuncBaseService.formatPcFuncShowTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE")));
            permCodeList.add(pcFuncBaseService.formatPcFuncConfigTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE")));
            permCodeList.add(pcFuncBaseService.formatPcFuncUpdateTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE")));
            permCodeList.add(pcFuncBaseService.formatPcFuncDeleteTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE")));
            //设置功能按钮的权限
            for (DynaBean eachButtonBean : funcButtonList) {
                if (eachFuncBean.getStr("JE_CORE_FUNCINFO_ID").equals(eachButtonBean.getStr("RESOURCEBUTTON_FUNCINFO_ID"))) {
                    buttonPermMap.put(pcFuncButtonService.formatPcFuncButtonShowTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE"), eachButtonBean.getStr("RESOURCEBUTTON_CODE")), eachButtonBean.getStr("RESOURCEBUTTON_CODE"));
                    buttonPermMap.put(pcFuncButtonService.formatPcFuncButtonUpdateTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE"), eachButtonBean.getStr("RESOURCEBUTTON_CODE")), eachButtonBean.getStr("RESOURCEBUTTON_CODE"));
                    buttonPermMap.put(pcFuncButtonService.formatPcFuncButtonDeleteTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE"), eachButtonBean.getStr("RESOURCEBUTTON_CODE")), eachButtonBean.getStr("RESOURCEBUTTON_CODE"));

                    permCodeList.add(pcFuncButtonService.formatPcFuncButtonShowTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE"), eachButtonBean.getStr("RESOURCEBUTTON_CODE")));
                    permCodeList.add(pcFuncButtonService.formatPcFuncButtonUpdateTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE"), eachButtonBean.getStr("RESOURCEBUTTON_CODE")));
                    permCodeList.add(pcFuncButtonService.formatPcFuncButtonDeleteTemplate(eachFuncBean.getStr("FUNCINFO_FUNCCODE"), eachButtonBean.getStr("RESOURCEBUTTON_CODE")));
                }
            }
        }

        List<DynaBean> permBeanList = metaService.select("JE_RBAC_PERM", ConditionsWrapper.builder().in("PERM_CODE", permCodeList));
        if (permBeanList != null && !permBeanList.isEmpty()) {
            for (DynaBean eachPermBean : permBeanList) {
                if (PermissionTypeEnum.FUNC_PC_BASE.name().equals(eachPermBean.getStr("PERM_TYPE_CODE"))) {
                    //功能基础权限
                    if (eachPermBean.getStr("PERM_CODE").lastIndexOf("-show") != -1) {
                        //展示权限
                        eachPermBean.set("PERM_CODE", pcFuncBaseService.formatPcFuncShowTemplate(targetFuncCode));
                        eachPermBean.set("PERM_OBJECT", targetFuncCode);
                    } else if (eachPermBean.getStr("PERM_CODE").lastIndexOf("-update") != -1) {
                        //更新权限
                        eachPermBean.set("PERM_CODE", pcFuncBaseService.formatPcFuncUpdateTemplate(targetFuncCode));
                        eachPermBean.set("PERM_OBJECT", targetFuncCode);
                    } else if (eachPermBean.getStr("PERM_CODE").lastIndexOf("-delete") != -1) {
                        //删除权限
                        eachPermBean.set("PERM_CODE", pcFuncBaseService.formatPcFuncDeleteTemplate(targetFuncCode));
                        eachPermBean.set("PERM_OBJECT", targetFuncCode);
                    } else {
                        continue;
                    }
                } else if (PermissionTypeEnum.FUNC_PC_CONFIG.name().equals(eachPermBean.getStr("PERM_TYPE_CODE"))) {
                    //功能配置权限
                    eachPermBean.set("PERM_CODE", pcFuncBaseService.formatPcFuncConfigTemplate(targetFuncCode));
                    eachPermBean.set("PERM_OBJECT", targetFuncCode);
                } else if (PermissionTypeEnum.BUTTON_PC.name().equals(eachPermBean.getStr("PERM_TYPE_CODE"))) {
                    //按钮配置权限
                    if (eachPermBean.getStr("PERM_CODE").lastIndexOf("-show") != -1) {
                        //展示权限
                        eachPermBean.set("PERM_CODE", pcFuncButtonService.formatPcFuncButtonShowTemplate(targetFuncCode, buttonPermMap.get(eachPermBean.getStr("PERM_CODE"))));
                        eachPermBean.set("PERM_OBJECT", targetFuncCode);
                    } else if (eachPermBean.getStr("PERM_CODE").lastIndexOf("-update") != -1) {
                        //更新权限
                        eachPermBean.set("PERM_CODE", pcFuncButtonService.formatPcFuncButtonUpdateTemplate(targetFuncCode, buttonPermMap.get(eachPermBean.getStr("PERM_CODE"))));
                        eachPermBean.set("PERM_OBJECT", targetFuncCode);
                    } else if (eachPermBean.getStr("PERM_CODE").lastIndexOf("-delete") != -1) {
                        //删除权限
                        eachPermBean.set("PERM_CODE", pcFuncButtonService.formatPcFuncButtonDeleteTemplate(targetFuncCode, buttonPermMap.get(eachPermBean.getStr("PERM_CODE"))));
                        eachPermBean.set("PERM_OBJECT", targetFuncCode);
                    } else {
                        continue;
                    }
                } else {
                    continue;
                }
                metaService.update(eachPermBean);
            }
        }
        permissionLoadService.reloadAllTypedPermsCache();
    }

    @Override
    public void modifyFuncButtonPermCode(String funcCode, String oldButtonCode, String newButtonCode) {
        pcFuncButtonService.modifyPermCode(funcCode, oldButtonCode, newButtonCode);
        permissionLoadService.reloadAllTypedPermsCache();
    }

    @Override
    public void modifySubFuncPermCode(String funcCode, String oldSubFuncCode, String newSubFuncCode) {
        pcSubFuncRelationService.modifyPermCode(funcCode, oldSubFuncCode, newSubFuncCode);
        permissionLoadService.reloadAllTypedPermsCache();
    }

}
